﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Speech.Synthesis;

namespace Defilade
{
    public partial class Defilade : Form
    {
        private Settings settings = new Settings();
        private SpeechSynthesizer synthesizer = null;
        private RecognitionEngine recognitionEngine = null;

        public Defilade()
        {
            InitializeComponent();
            
            //Load settings if possible
            try
            {
                settings = Settings.LoadFrom(Settings.SETTINGS_FILE);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex);
            }

            //Enable debug menu if in debug mode
#if !DEBUG
            this.menuStrip1.Items.Remove(debugToolStripMenuItem);
#endif

            playerLatitudeTextBox.Text = settings.LastPlayerCoordinate.Latitude.ToString();
            playerLongitudeTextBox.Text = settings.LastPlayerCoordinate.Longitude.ToString();
            targetLatitudeTextBox.Text = settings.LastTargetCoordinate.Latitude.ToString();
            targetLongitudeTextBox.Text = settings.LastTargetCoordinate.Longitude.ToString();

            //Do this here so that the intial setting of the text doesn't cause a re-update of the textboxes
            playerLatitudeTextBox.TextChanged += new EventHandler(all_TextChanged);
            playerLongitudeTextBox.TextChanged += new EventHandler(all_TextChanged);
            targetLatitudeTextBox.TextChanged += new EventHandler(all_TextChanged);
            targetLongitudeTextBox.TextChanged += new EventHandler(all_TextChanged);
            
            //Apply the loaded settings
            UpdateRange();
            textToSpeechMenuItem.Checked = settings.UseTextToSpeech;
            voiceRecognitionMenuItem.Checked = settings.UseVoiceRecognition;
            confirmCoordinatesMenuItem.Checked = settings.ConfirmVoiceCoordinates;
        }

        void hook_KeyPress(object sender, KeyPressEventArgs e)
        {
            System.Console.WriteLine("User Pressed: " + e.KeyChar);
        }

        public void UpdateRange()
        {
            if (Coordinate.IsValid(playerLatitudeTextBox.Text)
                && Coordinate.IsValid(playerLongitudeTextBox.Text)
                && Coordinate.IsValid(targetLatitudeTextBox.Text)
                && Coordinate.IsValid(targetLongitudeTextBox.Text))
            {
                MapLocation playerLocation = new MapLocation(playerLatitudeTextBox.Text, playerLongitudeTextBox.Text);
                MapLocation targetLocation = new MapLocation(targetLatitudeTextBox.Text, targetLongitudeTextBox.Text);

                double range = playerLocation.DistanceTo(targetLocation);
                rangeTextBox.Text = Math.Round(range, 0).ToString();

                //Save these as the 'last' settings..
                settings.LastPlayerCoordinate = playerLocation;
                settings.LastTargetCoordinate = targetLocation;
            }
            else
            {
                rangeTextBox.Text = "Enter Lat/Lon as 'DD.MM.SS'";
            }
        }

        private void all_TextChanged(object sender, EventArgs e)
        {
            UpdateRange();
        }

        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SettingsDialog dialog = new SettingsDialog(settings);
            DialogResult result = dialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                settings = new Settings(dialog.Settings);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            settings.SaveTo(Settings.SETTINGS_FILE);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void all_Enter(object sender, EventArgs e)
        {
            if (sender is TextBox)
            {
                (sender as TextBox).SelectAll();
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox box = new AboutBox();
            box.ShowDialog();
        }

        void engine_RecognizedRangeRequest()
        {
            System.Console.WriteLine("RANGE IS: " + rangeTextBox.Text);
            if (synthesizer != null)
            {
                synthesizer.SpeakAsyncCancelAll();
                String message = String.Format(
                    "Distance to target is {0} meters. Repeat, Distance is {0} meters.",
                    rangeTextBox.Text);
                synthesizer.SpeakAsync(message);
            }
        }

        void engine_RecognizedCoordinate(RecognitionEngine.Subject subject, Coordinate recognizedCoordinate)
        {
            //Repeat range setting to user (if they have text-to-speech enabled)
            if (synthesizer != null && settings.ConfirmVoiceCoordinates)
            {
                synthesizer.SpeakAsyncCancelAll();
                string direction = (recognizedCoordinate is Longitude) ? "west" : "north";
                String message = String.Format("{0} at {1} point {2} point {3} degrees {4}",
                    subject.ToString(),
                    recognizedCoordinate.Degrees,
                    recognizedCoordinate.Minutes,
                    recognizedCoordinate.Seconds,
                    direction);
                synthesizer.SpeakAsync(message);
            }

            if (subject == RecognitionEngine.Subject.Player)
            {
                if (recognizedCoordinate is Latitude)
                {
                    playerLatitudeTextBox.Text = recognizedCoordinate.ToString();
                }
                else
                {
                    playerLongitudeTextBox.Text = recognizedCoordinate.ToString();
                }
            }
            else
            {
                if (recognizedCoordinate is Latitude)
                {
                    targetLatitudeTextBox.Text = recognizedCoordinate.ToString();
                }
                else
                {
                    targetLongitudeTextBox.Text = recognizedCoordinate.ToString();
                }
            }
        }

        private void voiceRecognitionMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            settings.UseVoiceRecognition = voiceRecognitionMenuItem.Checked;

            //Always clear the recognition engine, just in case...
            if (recognitionEngine != null)
            {
                recognitionEngine.RecognizedCoordinate -= new RecognitionEngine.CoordinateInputEventHandler(engine_RecognizedCoordinate);
                recognitionEngine.RecognizedRangeRequest -= new RecognitionEngine.ActionEventHandler(engine_RecognizedRangeRequest);
                recognitionEngine.Dispose();
                recognitionEngine = null;
            }

            if (voiceRecognitionMenuItem.Checked)
            {
                recognitionEngine = new RecognitionEngine();
                recognitionEngine.RecognizedCoordinate += new RecognitionEngine.CoordinateInputEventHandler(engine_RecognizedCoordinate);
                recognitionEngine.RecognizedRangeRequest += new RecognitionEngine.ActionEventHandler(engine_RecognizedRangeRequest);
            }
        }

        private void textToSpeechMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            settings.UseTextToSpeech = textToSpeechMenuItem.Checked;
            confirmCoordinatesMenuItem.Enabled = textToSpeechMenuItem.Checked;

            if (synthesizer != null)
            {
                synthesizer.SpeakAsyncCancelAll();
                synthesizer.Dispose();
                synthesizer = null;
            }

            if (textToSpeechMenuItem.Checked)
            {
                synthesizer = new SpeechSynthesizer();
            }
        }

        private void confirmCoordinatesMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            settings.ConfirmVoiceCoordinates = confirmCoordinatesMenuItem.Checked;
        }

        private void generateUncaughtExceptionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            throw new ApplicationException("HAHA! NEVER CATCH ME!");
        }
    }
}
